fix(plugins): an upgrade no longer 404s every published page - #359
Open
mostafasadeghidev wants to merge 1 commit into
Open
fix(plugins): an upgrade no longer 404s every published page#359mostafasadeghidev wants to merge 1 commit into
mostafasadeghidev wants to merge 1 commit into
Conversation
Published HTML links a plugin's frontend assets by version — `/uploads/plugins/<id>/<version>/frontend/app.js` — because the version is what makes the URL cache-bustable. The upgrade flow deleted the old version's directory as its last step, and nothing re-rendered the artefacts already on disk, so every one of them kept pointing at files that were gone. On a real site an upgrade took out jQuery, GSAP, Lenis, Splide and the boot script across all six pages at once — the entire site's JavaScript, silently. Nothing warned, nothing prompted a re-publish, and the pages still returned 200 with a correct-looking document. The fix was one publish, for someone who already knew that. So the delete belongs at publish, not at upgrade. A publish is the only thing that rewrites those URLs, which makes it the exact moment the old files stop being referenced. `sweepStalePluginVersionAssets` runs after the slot swap and drops every version directory except the installed one. Between an upgrade and the next publish both versions sit on disk: the installed one for new renders, the previous one for pages not yet re-baked. The cost is bounded by how many upgrades happen between two publishes, and each version is a bundle rather than a library. A plugin with no installed record is never swept. Uninstall already removes its tree, so anything still there is unexplained — and a publish is a bad moment to act on something unexplained. Sweep failure is logged and swallowed: leftover files are wasted disk, never a broken page. Rollback still deletes the NEW version's directory, which is correct — no published page has ever referenced it.
mostafasadeghidev
marked this pull request as ready for review
August 9, 2026 03:00
mostafasadeghidev
added a commit
to mostafasadeghidev/Instatic
that referenced
this pull request
Aug 9, 2026
Brings in six upstream commits — collaborative-persistence and deterministic publishing, HEAD answered like GET on published pages, runtime script diagnostics, context-menu and data-token polish, the Selectors panel Used filter, and floating panels clearing docked sidebars. One of ours is now redundant and is dropped. Upstream's `e9e99dff` solves the opaque publish failure that CoreBunch#358 solved, and solves it better: its message carries `path:line:column`, mine carried only the diagnostic text. Its `RuntimeScriptBuildError` replaces `PublishRuntimeBuildError`, and both of my files are deleted rather than kept beside it. Three conflicts, all in the publish path or its tests: - `publishSite.ts` and `handlers/cms/publish.ts` — the same fix from two sides. Took upstream's wholesale and re-applied only the stale-plugin-asset sweep (CoreBunch#359), which upstream does not have. - `tables.test.ts` — not a contested edit at all: both sides had added an independent suite to one file (ours `created_by_plugin_id`, theirs `route_base`). Split into two describes with their own preamble; all ten pass. Two of our own gates needed the fix, not the exception: - `siteImport/types.ts` sat 2 lines over the 700-line ceiling because the file was already at 696 upstream and CoreBunch#349 added a six-line doc comment. Tightened our own prose rather than raising the ceiling or extracting a single union member into a module of its own. - The ContentPage bundle cap is raised 90 → 92 KB on this fork only, with the reason recorded in the budget entry: the stack layers twelve pending features whose shared imports land in that chunk, and each is inside 90 KB on its own branch. One test asserted the behaviour CoreBunch#359 deliberately changed — that an upgrade deletes the old version's directory. Updated to assert the new contract, with the reason, since that assertion is exactly what broke live sites. Verified: `bun run build` clean, `tsc -b` clean. Full suite compared against a clean upstream-main worktree — 327 failures there, and after these fixes the only remaining difference is environment flake (`EBUSY` on the Windows temp-db teardown, which hits upstream too). Zero architecture gates added. Both plugins typecheck and pass against the merged engine.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
Published HTML links a plugin's frontend assets by version —
/uploads/plugins/<id>/<version>/frontend/app.js— because the version is what makes the URL cache-bustable.The upgrade flow deleted the old version's directory as its last step. Nothing re-renders the artefacts already baked to disk, so every one of them kept pointing at files that were gone.
On a real site an upgrade took out jQuery, GSAP, Lenis, Splide and the boot script across all six pages at once — the entire site's JavaScript. Nothing warned, nothing prompted a re-publish, and the pages still returned
200with a correct-looking document. Only the browser console showed it.publishSite.tsdescribes the baked slot as "a self-contained static export". Plugin frontend assets are the one thing referenced from outside it, which is what made that description untrue.The change
The delete moves from upgrade to publish. A publish is the only thing that rewrites those URLs, which makes it the exact moment the old files stop being referenced — so
sweepStalePluginVersionAssetsruns after the slot swap and drops every version directory except the installed one.Between an upgrade and the next publish both versions sit on disk: the installed one for new renders, the previous one for pages not yet re-baked. The cost is bounded by how many upgrades happen between two publishes, and each version is a bundle rather than a library.
Two deliberate refusals:
Rollback still deletes the new version's directory, which is correct: no published page has ever referenced it.
Impact
Fixes silent breakage on every site that upgrades a plugin contributing
frontend.assets. No schema change. Disk usage between publishes grows by one bundle per upgrade, reclaimed at the next publish.Verification